package com.example.orderservice.service;

import com.example.orderservice.entity.OutboxEvent;
import com.example.orderservice.repository.OutboxEventRepository;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;

/**
 * Outbox 事件处理器
 * 负责处理未发送的事件，保障事务一致性
 */
@Slf4j
@Service
public class OutboxEventProcessor {
    
    @Autowired
    private OutboxEventRepository outboxEventRepository;
    
    @Autowired
    private RocketMQTemplate rocketMQTemplate;
    
    @Autowired
    private ObjectMapper objectMapper;
    
    private static final String ORDER_TOPIC = "ORDER_EVENTS";
    
    /**
     * 定时处理未发送的事件
     * 每5秒执行一次
     */
    @Scheduled(fixedDelay = 5000)
    @Async
    public void processUnprocessedEvents() {
        try {
            List<OutboxEvent> unprocessedEvents = outboxEventRepository.findUnprocessedEvents();
            
            for (OutboxEvent event : unprocessedEvents) {
                processEvent(event);
            }
            
        } catch (Exception e) {
            log.error("处理未发送事件时发生异常: {}", e.getMessage(), e);
        }
    }
    
    /**
     * 处理单个事件
     */
    @Transactional
    public void processEvent(OutboxEvent event) {
        try {
            log.info("开始处理 Outbox 事件: ID={}, 类型={}, 聚合ID={}", 
                event.getId(), event.getEventType(), event.getAggregateId());
            
            // 发送到 RocketMQ
            rocketMQTemplate.syncSend(
                ORDER_TOPIC + ":" + event.getEventType(),
                MessageBuilder.withPayload(event.getEventData()).build()
            );
            
            // 标记为已处理
            event.setProcessed(true);
            event.setProcessedAt(LocalDateTime.now());
            outboxEventRepository.save(event);
            
            log.info("Outbox 事件处理成功: ID={}, 类型={}", event.getId(), event.getEventType());
            
        } catch (Exception e) {
            log.error("处理 Outbox 事件失败: ID={}, 错误={}", event.getId(), e.getMessage(), e);
            
            // 增加重试次数
            event.setRetryCount(event.getRetryCount() + 1);
            outboxEventRepository.save(event);
            
            // 如果超过最大重试次数，标记为失败
            if (event.getRetryCount() >= event.getMaxRetries()) {
                log.error("Outbox 事件重试次数超限，标记为失败: ID={}", event.getId());
                event.setProcessed(true); // 标记为已处理，避免继续重试
                outboxEventRepository.save(event);
            }
        }
    }
    
    /**
     * 手动处理指定聚合的所有未处理事件
     */
    @Transactional
    public void processEventsForAggregate(String aggregateId) {
        List<OutboxEvent> events = outboxEventRepository.findUnprocessedEventsByAggregateId(aggregateId);
        
        for (OutboxEvent event : events) {
            processEvent(event);
        }
    }
}

